#include "../common.h"
//mqtt config
const char *mqttServer = "bemfa.com";
const uint16_t MQTT_PORT = 9501;
const std::string clientId = "";
const std::vector<String> topics = { "test001", "test002", "test003" };

WiFiClient wifiClient;
MQTTClient mqttClient(1024);

namespace _MQTTService {
void mqttMessageCallback(String topic, String payload) {
	Serial.println("incoming: " + topic + " - " + payload);
	TaskCtx<String> *ctx = new TaskCtx<String>(payload);
	EventService::trigger(EVENT_SERIAL_MESSAGE, ctx);
}

void wifi_connected(TaskCtx<void*>*) {
	App.pMQTTService->startMQTT();
}
void loop(TaskCtx<void*>*) {
	while (true) {
		Task::delay(500);
		if (!App.pWifiService->isConnected()) {
			continue;
		}
		if (!mqttClient.loop()) {
			App.pMQTTService->startMQTT();
		}
	}
}
}

void MQTTService::prepare0() {
	EventService::registerHandle(EVENT_WIFI_CONNECTED, &_MQTTService::wifi_connected);
}
void MQTTService::start() {
	//startMQTT();
}
void MQTTService::startMQTT() {
	if (clientId.empty()) {
		Serial.println("mqtt  clientId is empty no run");
		return;
	}

	if (_mqttLock) {
		return;
	}

	if (!App.pWifiService->isConnected()) {
		return;
	}
	if (mqttClient.connected()) {
		return;
	}

	_mtxMQTTLock.lock();
	if (_mqttLock || mqttClient.connected()) {
		_mtxMQTTLock.unlock();
		return;
	}
	Serial.println("mqtt  startMQTT");
	_mqttLock = true;
	try {
		mqttClient.disconnect();
		mqttClient.onMessage(_MQTTService::mqttMessageCallback);
		mqttClient.setTimeout(3000);
		mqttClient.begin(mqttServer, MQTT_PORT, wifiClient);
		Serial.println("mqtt  connect");
		while (!mqttClient.connect(clientId.c_str())) {
			Serial.print(".");
			delay(2000);
		}
		Serial.print("mqtt  connected : currCpu ");
		Serial.println(xPortGetCoreID());

		for (auto topic : topics) {
			mqttClient.subscribe(topic);
		}
		this->publishMessage(topics[0], "hello 我来了");
	} catch (...) {
		Serial.println("mqtt  error");
	}
	_mqttLock = false;

	if (!this->runLooFlag) {
		this->runLooFlag = true;
		//Task::run(&_MQTTService::loop);
	}
	_mtxMQTTLock.unlock();
}
void MQTTService::loop() {
	if (!this->runLooFlag) {
		return;
	}
	if (!App.pWifiService->isConnected()) {
		return;
	}
	if (!mqttClient.loop()) {
		App.pMQTTService->startMQTT();
	}
}

void MQTTService::publishMessage(const String &topic, const String &payload) {
	startMQTT();
	boolean send = mqttClient.publish(topic, payload);
	if (!send) {
		startMQTT();
	}
}
void MQTTService::close() {
	mqttClient.disconnect();
}

